/**
 * @file TcpConnection.h
 * @author your name (you@domain.com)
 * @brief
 * @version 0.1
 * @date 2022-04-05
 *
 * @copyright Copyright (c) 2022
 *
 */

#pragma once

#include "../utils/Noncopyable.h"
#include "InetAddress.h"
#include "Socket.h"
#include "SocketIO.h"

#include <functional>
#include <memory>
#include <string>

namespace wd
{

class EpollEvent;
class TcpConnection;
typedef std::shared_ptr<TcpConnection> TcpConnectionPtr;

class TcpConnection : Noncopyable,
                      public std::enable_shared_from_this<TcpConnection>
{
  public:
    typedef std::function<void(const TcpConnectionPtr &)> TcpConnectionCallback;
    TcpConnection(int sockfd, EpollEvent *loop);
    ~TcpConnection();

    std::string receive();
    void send(const std::string &msg);
    void sendAndClose(const std::string &msg);
    void sendInLoop(const std::string &msg);
    void shutdown();

    std::string toString();

    void setConnectionCallback(TcpConnectionCallback cb);
    void setMessageCallback(TcpConnectionCallback cb);
    void setCloseCallback(TcpConnectionCallback cb);

    void handleConnectionCallback();
    void handleMessageCallback();
    void handleCloseCallback();

  private:
    Socket sockfd_;
    SocketIO sockIO_;
    const InetAddress localAddr_;
    const InetAddress peerAddr_;
    bool isShutdownWrite_;
    EpollEvent *loop_;

    TcpConnectionCallback onConnectionCb_;
    TcpConnectionCallback onMessageCb_;
    TcpConnectionCallback onCloseCb_;
};

} // end of namespace wd
